package com.douya.pangu.application.basic.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.douya.common.ex.EmptyResultException;
import com.douya.common.pojo.dto.PagerDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.douya.common.utils.BeanUtils;
import com.douya.pangu.application.basic.mapper.CoreUserMapper;
import com.douya.pangu.application.basic.pojo.entity.CoreUserDO;
import com.douya.pangu.core.api.sys.fegin.UserDetailsImpl;
import com.douya.pangu.core.api.sys.pojo.dto.CoreUserDTO;
import com.douya.pangu.core.api.sys.pojo.vo.CoreUserVO;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;

import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 说明：核心用户表服务类
 *
 * @author hcy
 * @date 2022/11/28
 */
@Slf4j
@Service
@Transactional(readOnly = true)
public class CoreUserService extends MPJBaseServiceImpl<CoreUserMapper, CoreUserDO> {

    @Resource
    CoreUserMapper mCoreUserMapper;

    /**
     * 分页获取核心用户表
     *
     * @param pager 分页条件
     * @return 分页信息
     */
    public IPage<CoreUserVO> page(PagerDTO pager) {
        CoreUserDO mCoreUser = new CoreUserDO();
        IPage<CoreUserDO> selectPage = mCoreUserMapper.selectPage(
                pager.toPage(mCoreUser), pager.toQuery(mCoreUser)
        );
        return selectPage.convert(
                item -> {
                    CoreUserVO coreUser = new CoreUserVO();
                    BeanUtils.copyProperties(item, coreUser);
                    return coreUser;
                }
        );
    }

    /**
     * 根据ID获取核心用户表的VO对象
     *
     * @param id ID
     * @return 核心用户表，匹配不到抛出异常
     */
    public CoreUserVO findById(Long id) {
        CoreUserDO coreUser = getById(id);
        if (coreUser == null) {
            throw new EmptyResultException();
        }
        CoreUserVO temp = new CoreUserVO();
        BeanUtils.copyProperties(coreUser, temp);
        return temp;
    }

    /**
     * 查找核心用户表
     *
     * @return 核心用户表列表
     */
    public List<CoreUserVO> findAllUser() {
        List<CoreUserDO> userList = mCoreUserMapper.selectList(
                new QueryWrapper<>()
        );
        if (CollectionUtil.isEmpty(userList)) {
            throw new EmptyResultException();
        }
        return userList.parallelStream().map(item -> {
            CoreUserVO temp = new CoreUserVO();
            BeanUtils.copyProperties(item, temp);
            return temp;
        }).collect(Collectors.toList());
    }

    /**
     * 新增/修改核心用户表
     *
     * @param coreUserDTO 核心用户表
     */
    @Transactional(rollbackFor = Throwable.class)
    public void insert(CoreUserDTO coreUserDTO) {
        CoreUserDO coreUserDO = new CoreUserDO();
        BeanUtils.copyProperties(coreUserDTO, coreUserDO);
        saveOrUpdate(coreUserDO);
        // 异步MQ发送消息 通知其他服务 双写一致性

    }

    /**
     * 根据ID删除核心用户表
     *
     * @param id ID
     */
    @Transactional(rollbackFor = Throwable.class)
    public void delete(Long id) {
        mCoreUserMapper.deleteById(id);
    }

    /**
     * 查询SysUserDetails
     *
     * @param id 用户id
     */
    public UserDetailsImpl selectByUserId(Long id) {
        CoreUserDO user = mCoreUserMapper.selectById(id);
        if (user == null) {
            throw new UsernameNotFoundException(
                    String.format("No user found with id '%s'.", id)
            );
        }
        List<String> permissionList = userPermissionList(id);
        return new UserDetailsImpl(
                String.valueOf(user.getId()),
                user.getLoginName(),
                user.getLoginPassword(),
                CollectionUtil.isEmpty(permissionList) ? Collections.emptyList() :
                        permissionList.parallelStream()
                                .map(SimpleGrantedAuthority::new)
                                .collect(Collectors.toList())
        );
    }

    /**
     * 查询用户权限
     *
     * @param id 用户id
     */
    public List<String> userPermissionList(Long id) {
        List<String> permissionList = Lists.newArrayList();
        List<String> userPermissionList = mCoreUserMapper.permissionCodeByUserId(id);
        if (CollectionUtil.isNotEmpty(userPermissionList)) {
            permissionList.addAll(userPermissionList);
        }
        return permissionList.parallelStream()
                .filter(StrUtil::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
    }

}
